package ru.edu.vstu.atpp.acm.ui.services;

import org.apache.tapestry5.SymbolConstants;
import org.apache.tapestry5.ValueEncoder;
import org.apache.tapestry5.hibernate.HibernateSymbols;
import org.apache.tapestry5.ioc.MappedConfiguration;
import org.apache.tapestry5.ioc.OrderedConfiguration;
import org.apache.tapestry5.ioc.ServiceBinder;
import org.apache.tapestry5.ioc.annotations.Contribute;
import org.apache.tapestry5.ioc.services.ApplicationDefaults;
import org.apache.tapestry5.ioc.services.SymbolProvider;
import org.apache.tapestry5.services.ComponentRequestFilter;
import org.apache.tapestry5.services.ComponentRequestHandler;
import org.apache.tapestry5.services.ValueEncoderFactory;
import org.apache.tapestry5.services.ValueEncoderSource;
import ru.edu.vstu.atpp.acm.ui.entities.Groups;
import ru.edu.vstu.atpp.acm.ui.entities.Tema;
import ru.edu.vstu.atpp.acm.ui.security.AuthenticationFilter;
import ru.edu.vstu.atpp.acm.ui.services.authenticator.Authenticator;
import ru.edu.vstu.atpp.acm.ui.services.authenticator.AuthenticatorImpl;
import ru.edu.vstu.atpp.acm.ui.services.dao.AuthorsDAO;
import ru.edu.vstu.atpp.acm.ui.services.dao.GroupsDAO;
import ru.edu.vstu.atpp.acm.ui.services.dao.TemaDAO;
import ru.edu.vstu.atpp.acm.ui.services.dao.impl.AuthorsDAOImpl;
import ru.edu.vstu.atpp.acm.ui.services.dao.impl.GroupsDAOImpl;
import ru.edu.vstu.atpp.acm.ui.services.dao.impl.TemaDAOImpl;
import ru.edu.vstu.atpp.acm.ui.services.encoder.GroupsEncoder;
import ru.edu.vstu.atpp.acm.ui.services.encoder.TemaEncoder;

/**
 * Модуль приложения
 */
public class AppModule {

    /**
     * Привязка сервисов
     *
     * @param binder
     */
    public static void bind(ServiceBinder binder) {
        binder.bind(TemaDAO.class, TemaDAOImpl.class);
        binder.bind(AuthorsDAO.class, AuthorsDAOImpl.class);
        binder.bind(Authenticator.class, AuthenticatorImpl.class);
        binder.bind(GroupsDAO.class, GroupsDAOImpl.class);
    }

    @Contribute(SymbolProvider.class)
    @ApplicationDefaults
    public static void contributeApplicationDefaults(MappedConfiguration<String, String> configuration) {

        configuration.add(HibernateSymbols.PROVIDE_ENTITY_VALUE_ENCODERS, "false");
        //configuration.add(HibernateSymbols.ENTITY_SESSION_STATE_PERSISTENCE_STRATEGY_ENABLED, "true");
        configuration.add(SymbolConstants.PRODUCTION_MODE, "false");
        /*configuration.add(SymbolConstants.APPLICATION_CATALOG,
                "classpath:ru/edu/vstu/atpp/acm/ui/messages/Messages.properties");
*/
        // Поддерживаемые локали
        configuration.add(SymbolConstants.SUPPORTED_LOCALES, "ru,en");
    }


    @Contribute(ValueEncoderSource.class)
    public static void provideEncoders(
            MappedConfiguration<Class, ValueEncoderFactory> configuration,
            TemaDAO temaDAO,
            GroupsDAO groupsDAO) {

        contributeEncoder(configuration, Tema.class, new TemaEncoder(temaDAO));
        contributeEncoder(configuration, Groups.class, new GroupsEncoder(groupsDAO));
    }

    private static <T> void contributeEncoder(MappedConfiguration<Class, ValueEncoderFactory> configuration,
                                              Class<T> clazz, final ValueEncoder<T> encoder) {

        ValueEncoderFactory<T> factory = new ValueEncoderFactory<T>() {

            public ValueEncoder<T> create(Class<T> clazz) {
                return encoder;
            }
        };

        configuration.add(clazz, factory);
    }


    @Contribute(ComponentRequestHandler.class)
    public static void contributeComponentRequestHandler(
            OrderedConfiguration<ComponentRequestFilter> configuration) {
        configuration.addInstance("RequiresLogin", AuthenticationFilter.class);
    }
}
